package com.itheima.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.aliyuncs.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hankcs.algorithm.AhoCorasickDoubleArrayTrie;
import com.itheima.admin.mapper.AdSensitiveMapper;
import com.itheima.admin.pojo.AdSensitive;
import com.itheima.admin.service.WemediaNewsAutoScanService;
import com.itheima.common.constants.BusinessConstants;
import com.itheima.common.util.ali.AliGreenScanner;
import com.itheima.common.vo.ResultVo;
import com.itheima.dfs.feign.DfsFeign;
import com.itheima.wemedia.dto.WmNewsContentNodeDto;
import com.itheima.wemedia.feign.WmNewsFeign;
import com.itheima.wemedia.pojo.WmNews;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class WemediaNewsAutoScanServiceImpl implements WemediaNewsAutoScanService {

    @Autowired
    private WmNewsFeign wmNewsFeign;

    @Autowired
    private AdSensitiveMapper adSensitiveMapper;

    @Autowired
    private AliGreenScanner aliGreenScanner;

    @Autowired
    private DfsFeign dfsFeign;

   /* @Autowired
    private DFS*/

    @Override
    public void autoScanWemediaNewsById(String newId, String id) {

        //1.调用文章自媒体的id
        int int_NewId = Integer.parseInt(newId);

        ResultVo<WmNews> wmNewsResultVo = wmNewsFeign.getWmNewsById(int_NewId);
        //1.1判断是否查询到数据
       if (!wmNewsResultVo.isSuccess()){
            log.info("出错： 文章自动审核出错，id ={} ,int_NewId ={}",id,int_NewId);
            return;
       }

        WmNews wmNews = wmNewsResultVo.getData();
        if (null ==wmNews){
            log.info("出错： 文章自动审核出错，id ={} ,int_NewId ={}",id,int_NewId);
            return;
        }
        //1.2文章是否为审核状态，审核状态才需要处理
        if (wmNews.getStatus()!= BusinessConstants.WmNewsConstants.STATUS_SUBMIT){
            log.info("出错： 文章自动审核出错，id ={} ,int_NewId ={}",id,int_NewId);
            return;
        }

        //2.文本处理
        //2.1处理文本内容
        String text =  getTextFromWmNews(wmNews);

        //2.2敏感词在检测
        WmNews updatePojo = new WmNews();
        updatePojo.setId(wmNews.getId());


        if (sensitiveWordsCheck(text)){
            //有敏感词审核不通过
            updatePojo.setStatus(BusinessConstants.WmNewsConstants.STATUS_BLOCK);
            updatePojo.setReason("文章含有敏感词");
        }else {
            //文本反垃圾
            //使用阿里云的文本反垃圾
            try {
                Map<String, String> scanResult = aliGreenScanner.greenTextScan(text);
                String suggestion = scanResult.get("suggestion");
                //3.2内容没垃圾，才需要照片垃圾检测
                if (BusinessConstants.ScanConstants.PASS.equals(scanResult.get("suggestion"))){
                    //4.没有垃圾就进行图片反垃圾检测
                    //4.1提取 文章中的图片
                 List<String> imageList = getImagesFromWmNews(wmNews);
                 if (CollectionUtils.isNotEmpty(imageList)){
                     //4.2远程调用dfs服务，批量下载图片
                     ResultVo<List<byte[]>> downloadResult = dfsFeign.download(imageList);
                        if (!downloadResult.isSuccess()){
                            log.info("出错： 文章自动审核出错，id ={} ,int_NewId ={}",id,int_NewId);
                            return;
                        }

                     List<byte[]> imageDataList = downloadResult.getData();
                     scanResult = aliGreenScanner.imageScan(imageDataList);

                     suggestion = scanResult.get("suggestion");


                 }
               }
                // 解析结果
                switch (suggestion){
                    case BusinessConstants.ScanConstants.BLOCK:
                        updatePojo.setStatus(BusinessConstants.WmNewsConstants.STATUS_BLOCK);
                        updatePojo.setReason("内容违反相关规定");
                        break;
                    case BusinessConstants.ScanConstants.REVIEW:
                        // 需要人工审核
                        updatePojo.setStatus(BusinessConstants.WmNewsConstants.STATUS_MANUAL);
                        break;
                    case BusinessConstants.ScanConstants.PASS:
                        updatePojo.setStatus(BusinessConstants.WmNewsConstants.STATUS_PASS);
                        break;
                    default:
                        log.error("【出错】文章自动审核：uuid={},id={} 阿里反垃圾返回异常数据",id,int_NewId);
                        return;
                }

            } catch (Exception e) {
                log.error("【出错】文章自动审核：uuid={},id={} 调用阿里反垃圾失败",id,int_NewId,e);
                return;
            }
        }
        // 更新文章的状态
        ResultVo<WmNews> updateResult = wmNewsFeign.update(updatePojo);
        if(updateResult.isSuccess()){
            log.info("文章自动审核结果更新成功：uuid={},id={},status={}",id,int_NewId, updatePojo.getStatus());
        }else{
            log.error("【出错】文章自动审核：文章自动审核结果更新失败：uuid={},id={},status={}",id,int_NewId, updatePojo.getStatus());
        }
    }

    /**
     * 图片反垃圾
     * @param wmNews
     * @return
     */
    private List<String> getImagesFromWmNews(WmNews wmNews) {

        String content = wmNews.getContent();
        // 解析
        List<WmNewsContentNodeDto> contentNodeList = JSON.parseArray(content, WmNewsContentNodeDto.class);
        // stream()遍历contentNodeList, 取它每个元素来处理, filter条件满足true，则留下
        List<String> imageList = contentNodeList.stream().filter(node -> "image".equals(node.getType())).map(WmNewsContentNodeDto::getValue)
                .collect(Collectors.toList());
        // 添加封面, 封面多张时是以逗号分割
        String images = wmNews.getImages();
        if(StringUtils.isNotEmpty(images)){
            // 有封面
            String[] split = images.split(",");
            Collections.addAll(imageList, split);
        }
        return imageList;
    }

    /**
     * 敏感词的检测
     * @param text
     * @return
     */
    private boolean sensitiveWordsCheck(String text) {
            //1.铭感词的设置
            //2.构建一个map
            //3.构建字典
            //4.检测
            //5.返回结果
        // 获取数据库中的敏感词信息
        //querWrapper.select(只查询这里指定的列)
        QueryWrapper<AdSensitive> sensitives = Wrappers.<AdSensitive>query().select("sensitives");

        List<AdSensitive> sensitiveList = adSensitiveMapper.selectList(sensitives);
        if(CollectionUtils.isEmpty(sensitiveList)){
            return false;
        }
        // 转成map
        Map<String, String> map = sensitiveList.stream().collect(Collectors.toMap(AdSensitive::getSensitives, AdSensitive::getSensitives));
        // 构建字典树
        AhoCorasickDoubleArrayTrie<String> trie = new AhoCorasickDoubleArrayTrie<String>();
        trie.build(map);
        // 检测并返回，如果为null则代表没有敏感词
        return trie.findFirst(text) != null;


    }

    private String getTextFromWmNews(WmNews wmNews) {

        String content = wmNews.getContent();

        List<WmNewsContentNodeDto> wmNewsContentNodeList = JSON.parseArray(content, WmNewsContentNodeDto.class);

        List<String>  textList = wmNewsContentNodeList.stream().filter(node ->"text".equals(node.getType())).map(WmNewsContentNodeDto::getType)
                        .collect(Collectors.toList());

        //添加标题
        textList.add(wmNews.getTitle());
        //以逗号分割
        return  String.join(",",textList);
    }
}
